import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:kq_flutter_core_widget/utils/toast_util.dart';

/// 文件选择工具
///
/// 包括图片或文件选择
/// 其中文件选择仅支持Android端，iOS只支持选择图片
class FilePickerNativeUtil {
  static const _methodChannelName = 'flutter.keqiang.com/filePicker';

  static const _platformMethod = MethodChannel(_methodChannelName);

  /// 选择文件时，指定多语言文本资源
  static StringRes? stringRes;

  /// 拍照
  /// [compress]指定图片压缩后的大小，[compress]为null或[compress]<=0时不压缩，图片本身大小 <= [compress]时也不压缩，单位KB
  static Future<KqFile?> takePhoto({int? compress}) async {
    try {
      var result = await _platformMethod
          .invokeMethod('takePhoto', {'compress': compress});
      if (result['code'] == 1) {
        dynamic e = result['data'];
        return KqFile(
          fileName: e['fileName'],
          filePath: e['filePath'],
          fileLength: e['fileLength'],
          mime: e['mime'],
          suffix: e['suffix'],
          createDate: _toMilliseconds(e['createDate']),
          modifiedDate: _toMilliseconds(e['modifiedDate']),
        );
      } else if (result['code'] == 0) {
        var msg = result['msg'];
        KqToast.showNormal(msg);
      }
      return null;
    } on PlatformException catch (e) {
      debugPrint(e.message);
      return null;
    }
  }

  static int? _toMilliseconds(int? time) {
    if (time == null) {
      return null;
    }
    return time * 1000;
  }

  /// 选择图片
  /// [compress]指定图片压缩后的大小，[compress]为null或[compress]<=0时不压缩，图片本身大小 <= [compress]时也不压缩，单位KB。
  ///
  /// [preferredLayout]表示首选的布局方式，当[preferredLayout] == [PreferredLayout.grid]时，[spanCount]表示网格布局列数量。
  /// [preferredLayout]和[spanCount]仅支持android
  static Future<List<KqFile>> pickImages({
    int maxCount = 1,
    int? compress,
    PreferredLayout? preferredLayout,
    int? spanCount,
  }) async {
    try {
      var result = await _platformMethod.invokeMethod('pickImages', {
        'maxCount': maxCount,
        'compress': compress,
        'stringRes': stringRes?._toJson(),
        'preferredLayout': preferredLayout?.value,
        'spanCount': spanCount,
      });
      if (result['code'] == 1) {
        List<dynamic> data = result['data'];
        return data
            .map(
              (e) => KqFile(
                fileName: e['fileName'],
                filePath: e['filePath'],
                fileLength: e['fileLength'],
                mime: e['mime'],
                suffix: e['suffix'],
                createDate: _toMilliseconds(e['createDate']),
                modifiedDate: _toMilliseconds(e['modifiedDate']),
              ),
            )
            .toList();
      } else if (result['code'] == 0) {
        var msg = result['msg'];
        KqToast.showNormal(msg);
      }
      return [];
    } on PlatformException catch (e) {
      debugPrint(e.message);
      return [];
    }
  }

  /// 选择指定类型文件
  ///
  /// [extensions]为文件后缀，指定哪些类型文件可选，不传或空列表则表示所有文件可选
  ///
  /// [compress]指定图片压缩后的大小，[compress]为null或[compress]<=0时不压缩，图片本身大小 <= [compress]时也不压缩，
  /// 如果选择的文件非图片也不压缩，单位KB
  ///
  /// [preferredLayout]表示首选的布局方式，当[preferredLayout] == [PreferredLayout.grid]时，[spanCount]表示网格布局列数量。
  /// [preferredLayout]和[spanCount]仅支持android
  static Future<List<KqFile>> pickFiles({
    List<String>? extensions,
    int maxCount = 1,
    int? compress,
    PreferredLayout? preferredLayout,
    int? spanCount,
  }) async {
    try {
      var result = await _platformMethod.invokeMethod('pickFiles', {
        'maxCount': maxCount,
        'extensions': extensions,
        'compress': compress,
        'stringRes': stringRes?._toJson(),
        'preferredLayout': preferredLayout?.value,
        'spanCount': spanCount,
      });
      if (result['code'] == 1) {
        List<dynamic> data = result['data'];
        return data
            .map(
              (e) => KqFile(
                fileName: e['fileName'],
                filePath: e['filePath'],
                fileLength: e['fileLength'],
                mime: e['mime'],
                suffix: e['suffix'],
                createDate: _toMilliseconds(e['createDate']),
                modifiedDate: _toMilliseconds(e['modifiedDate']),
              ),
            )
            .toList();
      } else if (result['code'] == 0) {
        var msg = result['msg'];
        KqToast.showNormal(msg);
      }
      return [];
    } on PlatformException catch (e) {
      debugPrint(e.message);
      return [];
    }
  }
}

/// 文件选择结果
class KqFile {
  const KqFile({
    this.fileName,
    this.filePath,
    this.fileLength,
    this.suffix,
    this.mime,
    this.createDate,
    this.modifiedDate,
  });

  /// 文件名
  final String? fileName;

  /// 文件路径
  final String? filePath;

  /// 文件大小
  final int? fileLength;

  /// 文件后缀
  final String? suffix;

  /// MIME
  final String? mime;

  /// 文件创建时间,单位毫秒
  final int? createDate;

  /// 文件修改时间,单位毫秒
  final int? modifiedDate;

  @override
  String toString() {
    return 'KqFile{fileName: $fileName, filePath: $filePath, fileLength: $fileLength, suffix: $suffix, mime: $mime, createDate: $createDate, modifiedDate: $modifiedDate}';
  }
}

/// 常用文件的扩展名
enum Extension {
  txt('txt', MIME.txt),
  html('html', MIME.html),
  csv('csv', MIME.csv),
  json('json', MIME.json),
  jpeg('jpeg', MIME.jpeg),
  jpg('jpg', MIME.jpeg),
  png('png', MIME.png),
  gif('gif', MIME.gif),
  webp('webp', MIME.webp),
  pdf('pdf', MIME.pdf),
  zip('zip', MIME.zip),
  rar('rar', MIME.rar),
  jar('jar', MIME.jar),
  xls('xls', MIME.xls),
  xlsx('xlsx', MIME.xlsx),
  doc('doc', MIME.doc),
  docx('docx', MIME.docx),
  ppt('ppt', MIME.ppt),
  pptx('pptx', MIME.pptx),
  mp3('mp3', MIME.mp3),
  wav('wav', MIME.wav),
  mp4('mp4', MIME.mp4),
  apk('apk', MIME.apk);

  const Extension(this.name, this.mime);

  final String name;
  final String mime;
}

/// 常用文件类型的MIME
class MIME {
  /// .txt
  static const String txt = "text/plain";

  /// .html
  static const String html = "text/html";

  /// .csv
  static const String csv = "text/csv";

  /// .json
  static const String json = "application/json";

  /// .jpg
  static const String jpeg = "image/jpeg";

  /// 所有图片
  static const String image = "image/*";

  /// .png
  static const String png = "image/png";

  /// .gif
  static const String gif = "image/gif";

  /// .webp
  static const String webp = "image/webp";

  /// .pdf
  static const String pdf = "application/pdf";

  /// .zip
  static const String zip = "application/zip";

  /// .rar
  static const String rar = "application/x-rar-compressed";

  /// .jar
  static const String jar = "application/java-archive";

  /// .xls
  static const String xls = "application/vnd.ms-excel";

  /// .xlsx
  static const String xlsx =
      "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";

  /// .doc
  static const String doc = "application/msword";

  /// .docx
  static const String docx =
      "application/vnd.openxmlformats-officedocument.wordprocessingml.document";

  /// .ppt
  static const String ppt = "application/mspowerpoint";

  /// .pptx
  static const String pptx =
      "application/vnd.openxmlformats-officedocument.presentationml.presentation";

  /// .mp3
  static const String mp3 = "audio/mpeg";

  /// .wav
  static const String wav = "audio/wav";

  /// .mp4
  static const String mp4 = "video/mp4";

  /// .apk
  static const String apk = "application/vnd.android.package-archive";

  /// 未知
  static const String unknown = "application/octet-stream";
}

abstract class StringRes {
  /// 打开文档
  String get openDocument;

  /// 最近
  String get lately;

  /// 图片
  String get image;

  /// 音频
  String get audio;

  /// 视频
  String get video;

  /// 下载内容
  String get download;

  /// 根目录
  String get rootFolder;

  /// 文档
  String get document;

  /// 压缩包
  String get zip;

  /// 搜索内容
  String get searchContent;

  /// 无打开此文件的程序
  String get noValidThirdAppForFilePreviewHint;

  /// 文件查看失败
  String get filePreviewFailedHint;

  /// 文件选中格式化文本，如：已选择 1$d / 2$d
  String get fileChosenCountFormat;

  /// 搜索...
  String get search;

  /// 无任何文件
  String get emptyData;

  /// 排序方式
  String get sortType;

  /// 显示隐藏文件
  String get showHideFile;

  /// 不显示隐藏文件
  String get notShowHideFile;

  /// 文件名（从A到Z）
  String get sortFileNameAz;

  /// 文件名（从Z到A）
  String get sortFileNameZa;

  /// 修改日期（从旧到新）
  String get sortFileTimeAsc;

  /// 修改日期（从新到旧）
  String get sortFileTimeDesc;

  String _toJson() {
    var map = {
      'openDocument': openDocument,
      'lately': lately,
      'image': image,
      'audio': audio,
      'video': video,
      'download': download,
      'rootFolder': rootFolder,
      'document': document,
      'zip': zip,
      'searchContent': searchContent,
      'noValidThirdAppForFilePreviewHint': noValidThirdAppForFilePreviewHint,
      'filePreviewFailedHint': filePreviewFailedHint,
      'fileChosenCountFormat': fileChosenCountFormat,
      'search': search,
      'emptyData': emptyData,
      'sortType': sortType,
      'showHideFile': showHideFile,
      'notShowHideFile': notShowHideFile,
      'sortFileNameAz': sortFileNameAz,
      'sortFileNameZa': sortFileNameZa,
      'sortFileTimeAsc': sortFileTimeAsc,
      'sortFileTimeDesc': sortFileTimeDesc
    };
    return json.encode(map);
  }
}

/// 首选布局，仅支持android
enum PreferredLayout {
  grid(0),
  linear(1);

  const PreferredLayout(this.value);

  final int value;
}
